package com.stdz.counter.entity;

import com.stdz.counter.core.constant.ClearLoopType;
import com.stdz.counter.core.constant.DataMode;
import com.stdz.counter.core.constant.MeterModel;
import com.stdz.counter.utils.DateFormatUtil;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Date;

/**
 *
 */
public class MeterInfo implements Serializable {
    // 配置id
    private int meterId;
    // 名称
    private String meterName;

    private int meterModel;
    // ConnectType 串口/tcp/GPRS
    private int connectType;

    private String comPort;
    // 波特率
    private int baudRate;
    // DataMode:BCD/INT/FLOAT
    private int dataMode;
    // 设备id
    private byte modbusDeviceId;
    // 地址
    private int modbusPos;
    // 告警值1（较低）
    private String alarm1;
    // 告警值2（较高），超过重置
    private String alarm2;
    // 上排值（实际值）
    private int upperRowVal;
    // 下排值（下次告警值），alarm1或者alarm2
    private int lowerRowVal;
    // 小数位数
    private int decimalDigit;
    // 步进倍率
    private int scaleRate;
    // 暂停标识
    private int suspendFlag;
    // 清零方式
    private int clearMode;

    private int clearLoopType;

    private Date clearTime;

    private int online;

    private Date createTime;

    private Date updateTime;

    private Date syncTime;

    private Date lastClearTime;

    public int getMeterId() {
        return meterId;
    }

    public void setMeterId(int meterId) {
        this.meterId = meterId;
    }

    public int getMeterModel() {
        return meterModel;
    }

    public void setMeterModel(int meterModel) {
        this.meterModel = meterModel;
    }

    public String getComPort() {
        return comPort;
    }

    public void setComPort(String comPort) {
        this.comPort = comPort;
    }

    public byte getModbusDeviceId() {
        return modbusDeviceId;
    }

    public void setModbusDeviceId(byte modbusDeviceId) {
        this.modbusDeviceId = modbusDeviceId;
    }

    public int getModbusPos() {
        return modbusPos;
    }

    public void setModbusPos(int modbusPos) {
        this.modbusPos = modbusPos;
    }

    public String getAlarm1() {
        return alarm1;
    }

    public void setAlarm1(String alarm1) {
        this.alarm1 = alarm1;
    }

    public String getAlarm2() {
        return alarm2;
    }

    public void setAlarm2(String alarm2) {
        this.alarm2 = alarm2;
    }

    public int getUpperRowVal() {
        return upperRowVal;
    }

    public void setUpperRowVal(int upperRowVal) {
        this.upperRowVal = upperRowVal;
    }

    public int getLowerRowVal() {
        return lowerRowVal;
    }

    public void setLowerRowVal(int lowerRowVal) {
        this.lowerRowVal = lowerRowVal;
    }

    public int getScaleRate() {
        return scaleRate;
    }

    public void setScaleRate(int scaleRate) {
        this.scaleRate = scaleRate;
    }

    public int getSuspendFlag() {
        return suspendFlag;
    }

    public void setSuspendFlag(int suspendFlag) {
        this.suspendFlag = suspendFlag;
    }

    public int getClearMode() {
        return clearMode;
    }

    public void setClearMode(int clearMode) {
        this.clearMode = clearMode;
    }

    public String getMeterName() {
        return meterName;
    }

    public void setMeterName(String meterName) {
        this.meterName = meterName;
    }

    public int getDataMode() {
        return dataMode;
    }

    public void setDataMode(int dataMode) {
        this.dataMode = dataMode;
    }

    public int getDecimalDigit() {
        return decimalDigit;
    }

    public void setDecimalDigit(int decimalDigit) {
        this.decimalDigit = decimalDigit;
    }

    public int getConnectType() {
        return connectType;
    }

    public void setConnectType(int connectType) {
        this.connectType = connectType;
    }

    public int getBaudRate() {
        return baudRate;
    }

    public void setBaudRate(int baudRate) {
        this.baudRate = baudRate;
    }

    public Date getClearTime() {
        return clearTime;
    }

    public void setClearTime(Date clearTime) {
        this.clearTime = clearTime;
    }

    public int getOnline() {
        return online;
    }

    public void setOnline(int online) {
        this.online = online;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public Date getSyncTime() {
        return syncTime;
    }

    public void setSyncTime(Date syncTime) {
        this.syncTime = syncTime;
    }

    public int getClearLoopType() {
        return clearLoopType;
    }

    public void setClearLoopType(int clearLoopType) {
        this.clearLoopType = clearLoopType;
    }

    public String getDisplayUpperRowVal() {
        if (decimalDigit > 0) {
            if (dataMode == DataMode.FLOAT.getMode()) {
                float displayFloat = Float.intBitsToFloat(upperRowVal);
                NumberFormat nf = NumberFormat.getNumberInstance();
                nf.setMaximumFractionDigits(decimalDigit);
                return nf.format(displayFloat);
            }
            float displayFloat = (float) ((upperRowVal * 1f) / (Math.pow(10, decimalDigit)));
            return displayFloat + "";
        } else if (dataMode == DataMode.FLOAT.getMode()) {
            float displayFloat = Float.intBitsToFloat(upperRowVal);
            return displayFloat + "";
        }
        return "" + this.upperRowVal;
    }

    public String getDisplayLowerRowVal() {
        if (decimalDigit > 0) {
            if (dataMode == DataMode.FLOAT.getMode()) {
                float displayFloat = Float.intBitsToFloat(lowerRowVal);
                NumberFormat nf = NumberFormat.getNumberInstance();
                nf.setMaximumFractionDigits(decimalDigit);
                return nf.format(displayFloat);
            }
            float displayFloat = (float) ((lowerRowVal * 1f) / (Math.pow(10, decimalDigit)));
            return displayFloat + "";
        }
        return "" + this.lowerRowVal;
    }

    public String getDisplayAlarm1() {
        if (StringUtils.isBlank(this.alarm1)) {
            return "";
        }
        if (decimalDigit > 0) {
            float displayFloat = (float) ((Integer.parseInt(alarm1) * 1f) / (Math.pow(10, decimalDigit)));
            return displayFloat + "";
        }
        return "" + this.alarm1;
    }

    public String getDisplayAlarm2() {
        if (StringUtils.isBlank(this.alarm2)) {
            return "";
        }
        if (decimalDigit > 0) {
            float displayFloat = (float) ((Integer.parseInt(alarm2) * 1f) / (Math.pow(10, decimalDigit)));
            return displayFloat + "";
        }
        return "" + this.alarm2;
    }

    public String getDisplayScale() {
        if (meterModel == MeterModel.ST76.getModel()) {
            return "" + (this.scaleRate / 100000f);
        } else {
            return "" + (this.scaleRate / 10000f);
        }
    }

    public String getDisplayClearTime() {
        if (this.clearTime == null) {
            return "";
        }
        return DateFormatUtil.dateFormatString(this.clearTime, DateFormatUtil.STRING_DATE_FORMAT);
    }

    /**
     *
     * @param scaleRate
     * @return setResult true:success
     */
    public boolean setDisplayScaleRate(String scaleRate) {
        int iValue = 0;
        int decimalDigitIndex = scaleRate.indexOf(".");
        if (decimalDigitIndex >= 0) {
            try {
                float fValue = Float.parseFloat(scaleRate);
                if (meterModel == MeterModel.ST76.getModel()) { // * 100000
                    iValue = (int) Math.floor(fValue * 100000);
                } else {
                    iValue = (int) Math.floor(fValue * 10000);
                }
            } catch (NumberFormatException e) {
                return false;
            }
        } else {
            try {
                iValue= Integer.parseInt(scaleRate);
                if (meterModel == MeterModel.ST76.getModel()) { // * 100000
                    iValue = iValue * 100000;
                } else {
                    iValue = iValue * 10000;
                }
            } catch (NumberFormatException e) {
                return false;
            }
        }
        this.scaleRate = iValue;
        return true;
    }

    public boolean setDisplayAlarm1(String displayAlarm1) {
        int decimalDigitIndex = displayAlarm1.indexOf(".");
        if (decimalDigitIndex >= 0) {
            try {
                if (decimalDigit > 0) {
                    int iAlarm = (int) Math.floor(Float.parseFloat(displayAlarm1) * Math.pow(10, decimalDigit));
                    this.alarm1 = "" + iAlarm;
                } else {
                    int iAlarm = (int) Math.floor(Float.parseFloat(displayAlarm1));
                    this.alarm1 = "" + iAlarm;
                }
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        } else {
            try {
                if (decimalDigit > 0) {
                    int iAlarm = (int) (Integer.parseInt(displayAlarm1) * Math.pow(10, decimalDigit));
                    this.alarm1 = "" + iAlarm;
                } else {
                    int iAlarm = Integer.parseInt(displayAlarm1);
                    this.alarm1 = "" + iAlarm;
                }
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        }
    }

    public boolean setDisplayAlarm2(String displayAlarm2) {
        int decimalDigitIndex = displayAlarm2.indexOf(".");
        if (decimalDigitIndex >= 0) {
            try {
                if (decimalDigit > 0) {
                    int iAlarm = (int) Math.floor(Float.parseFloat(displayAlarm2) * Math.pow(10, decimalDigit));
                    this.alarm2 = "" + iAlarm;
                } else {
                    int iAlarm = (int) Math.floor(Float.parseFloat(displayAlarm2));
                    this.alarm2 = "" + iAlarm;
                }
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        } else {
            try {
                if (decimalDigit > 0) {
                    int iAlarm = (int) (Integer.parseInt(displayAlarm2) * Math.pow(10, decimalDigit));
                    this.alarm2 = "" + iAlarm;
                } else {
                    int iAlarm = Integer.parseInt(displayAlarm2);
                    this.alarm2 = "" + iAlarm;
                }
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        }
    }

    public Date getLastClearTime() {
        return lastClearTime;
    }

    public void setLastClearTime(Date lastClearTime) {
        this.lastClearTime = lastClearTime;
    }

    public void clearSuccess() {
        this.lastClearTime = clearTime;
        if (clearTime != null) {
            if (clearLoopType == ClearLoopType.LOOP_OPERTE.getLoopType()) {
                Calendar cal = Calendar.getInstance();
                cal.setTime(clearTime);
                cal.add(Calendar.DAY_OF_YEAR, 1);
                this.clearTime = cal.getTime();
            }
        }
    }

    public void clearOver() {
        if (clearTime != null) {
            ClearLoopType clearLoopType = ClearLoopType.getClearLoopType(this.clearLoopType);
            if (clearLoopType == ClearLoopType.LOOP_OPERTE) {
                long span = System.currentTimeMillis() - clearLoopType.getClearOverTime() +  - clearTime.getTime();
                long oneDayTimeMills = 1000L * 3600 * 24;
                int dayNum = (int) (span / oneDayTimeMills);
                int delayDays = (span % oneDayTimeMills == 0) ? dayNum : dayNum + 1;
                if (delayDays < 1) {
                    return;
                }
                Calendar cal = Calendar.getInstance();
                cal.setTime(clearTime);
                cal.add(Calendar.DAY_OF_YEAR, delayDays);
                this.clearTime = cal.getTime();
            }

        }
    }
}
